
import createFetchHook from "./hooks/createFetchHook";
// import createXMLHttpRequestHook from "./hooks/createXMLHttpRequestHook";
import createXMLHttpRequestHook from "./hooks/createXHRHook";
import creteNodeHook from "./hooks/creteNodeHook";

// const requestMiddlewares = window.__requestMiddlewares||[];
// const responseMiddlewares = window.__responseMiddlewares||[];
if(!window.__requestMiddlewares){
  window.__requestMiddlewares = []
}
if(!window.__responseMiddlewares){
  window.__responseMiddlewares = []
}
class RequestHook {
  options: RequestOptions;
  constructor(options:RequestOptions){
    this.options = options

  }
  add(fn:(ctx:ContextProps,handler:HandlerProps)=>void) {
    window.__requestMiddlewares.push({
      fn,
      options: this.options

    })
    return this;
  }
}
class ResponseHook {
  options: ResponseOptions;
  constructor(options:ResponseOptions){
    this.options = options
  }
  add(fn:(ctx:ContextProps,handler:HandlerProps)=>void) {
    window.__responseMiddlewares.push({
      fn,
      options: this.options
    })
    return this;
  } 
}

/**
 * 创建请求Hook
 * @returns 
 */
export function createRequestHook(options?:RequestOptions) {
  
  return  new RequestHook(options)
}
/**
 * 创建返回Hook
 * @returns 
 */
export function createResponseHook(options?:ResponseOptions) {
 
  return new ResponseHook(options);
}
const compose = (
  middlewares: any[],
  ctx: ContextProps,
  handler: HandlerProps
) => {
 middlewares = middlewares.filter(v=>{
  if(v.options&&Array.isArray(v.options.hook)){
    return v.options.hook.includes(ctx.resource)
  }
  return true
 })
  dispatch(0);
  function dispatch(i: number) {
    let middleware = middlewares[i];
    const _handler = {
      send(resBody:ResBodyType) {
        handler.send(resBody);
      },
      next() {
          dispatch(i + 1);
      },
    };
    if(middleware){
      middleware.fn(ctx, _handler);
    }else{
      handler.next(ctx)
    }
  }
};
//全局只有一个拦截
if(!window.__WEB_HOOKS){
  createFetchHook({
    onRequest(ctx:ContextProps, handler: HandlerProps) {
      compose(window.__requestMiddlewares, ctx, handler);
    },
    onResponse(
      ctx: ContextProps,
      handler: { next: (arg0: any) => void; send: () => void }
    ) {
      compose(window.__responseMiddlewares, ctx, handler);
  
    },
  });
  
  createXMLHttpRequestHook({
    onRequest(ctx: any, handler: any) {
      compose(window.__requestMiddlewares, ctx, handler);
  
    },
    onResponse(
      ctx: any,
      handler: { next: (arg0: any) => void; send: () => void }
    ) {
      compose(window.__responseMiddlewares, ctx, handler);
  
    },
  });
  creteNodeHook({
    onRequest(ctx, handler) {
      compose(window.__requestMiddlewares, ctx, handler);
  
    },
    onResponse(ctx, handler) {
      compose(window.__responseMiddlewares, ctx, handler);
  
    },
  })
  window.__WEB_HOOKS = true
}

export default {
  createRequestHook,
  createResponseHook
};
